#include <cstddef>
#include <cstdio>
#include <cstdlib>
#include <sstream>
#include <string.h>
#include <iostream>
#include <string>

extern "C" {

#include <libavformat/avformat.h>
#include <libavcodec/avcodec.h>
#include <libavutil/avutil.h>
#include <libswscale/swscale.h>
#include <libavutil/imgutils.h>
#include <libavformat/avio.h>
#include <libavutil/log.h>


}

void PrintAllFile(const std::string & path) {

    AVIODirContext * dir_ctx = NULL;
    AVIODirEntry   * entry   = NULL;

    char file_mode[25] = {0};
    char uid_and_gid[25] = {0};

    int result = avio_open_dir(&dir_ctx, path.c_str(), NULL);

    if (result < 0) {

        
        std::cout << "open dir failed result : " << result << std::endl; 
    } else {

        int cnt = 0;
        for(;;) {

            entry = NULL;
            if ((result = avio_read_dir(dir_ctx, &entry)) < 0) {

                std::cout << "avio read next file failed result : " << result << std::endl;
                break;
            }
            if (!entry) {

                break;
            }
            if (entry->filemode == -1) {

                snprintf(file_mode, sizeof(file_mode) - 1, "????");
            } else {

                snprintf(file_mode, sizeof(file_mode) - 1, "%ld", entry->filemode);
            }
            snprintf(uid_and_gid, sizeof(uid_and_gid) - 1, "%ld %ld", entry->user_id, entry->group_id);


            if (cnt == 0) {

                std::cout << "TYPE\tSIZE\tNAME\tUID(GID)\tUGO\tMODIFIED\tACCESSED\tSTATUS_CHANGED" << std::endl;
                cnt++;
            } 
            // 时间戳单位是ns
            std::cout << std::to_string(entry->type) << "\t"
                      << entry->size << "\t|"
                      << entry->name << "\t|"
                      << uid_and_gid << "\t|"
                      << file_mode   << "\t|"
                      << entry->modification_timestamp << "\t|"
                      << entry->access_timestamp << "\t|"
                      << entry->status_change_timestamp << "\t\n";
                 
            avio_free_directory_entry(&entry);
        }
    }
    if (dir_ctx) {

        avio_close_dir(&dir_ctx);
    }
}


int main(int argc, char * argv[]) {

    av_log_set_flags(AV_LOG_DEBUG);

    avformat_network_init();

    PrintAllFile(argv[1]);

    avformat_network_deinit();

    return EXIT_SUCCESS;
}